<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
    let _data1={
        a:12,
        arr:[1,2,3]
    };

    let p1 = new Proxy(_data1,{
        has(data,name){// 判断存在 'a' in p1
            if(name in data){
                return true
            }else{
                return false
            }
        },
        get(data,name){// 获取 p1.a
            if(name in data){
                return data[name]
            }else{
                throw new Error(`${name} 不存在`)
            }
        },
        set(data,name,val){
            data[name] = val;
        },
        deleteProperty(data,name){// 删除 delete p1.a
            if(name in data){
                return delete data[name]
            }else{
                throw new Error(`${name} 不存在`) 
            }
        }
    })
    
    // **********************************************************************
    class A{
        render(){
            console.log('渲染');
        }
    };
    let p2 = new Proxy(new A(),{
        set(obj,name,val){
            obj[name] = val;
            obj.render();
        }
    })

    // **********************************************************************
    class Cmp{
        constructor(text){
            this.text = text;
            this.el = document.createElement('div');
            this.el.className = 'box';
            document.body.appendChild(this.el);
            this.render();// 初次构造时需要启动
        }
        render(){
            console.log('Cmp 渲染');
            this.el.innerHTML = this.text;
        }
    }
    let _cmp = new Cmp('oy');
    let cmp= new Proxy(_cmp,{
        set(obj,name,val){
            obj[name] = val;
            obj.render();
        }
    })

    // **********************************************************************
    const Cmp2 = new Proxy(class{// 匿名类
        constructor(text){
            this.text = text;
            this.el = document.createElement('div');
            this.el.className = 'box';
            document.body.appendChild(this.el);
            this.render();
        }
        render(){
            console.log('Cmp2 渲染');
            this.el.innerHTML = this.text;
        }
    },{
        construct(cls,args){// Proxy 的 construct 用来监听 class 的 new
            console.log('Cmp2 construct');
            // return {}// 必须返回
            let obj = new cls(...args);
            return new Proxy(obj,{// 必须返回 Proxy
                set(obj,name,val){
                    obj[name] = val;
                    obj.render();
                }
            });
        }
    });
    let cpm2 = new Cmp2('oy2');

    // **********************************************************************
    // 用原生方式实现可响应
    class Cmp3{
        constructor(text){
            this.text = text;
            this.el = document.createElement('div');
            this.el.className = 'box';
            document.body.appendChild(this.el);
            this.render();// 初次构造时需要启动
        }
        render(){
            console.log('Cmp3 渲染');
            this.el.innerHTML = this.text;
        }
        set(name,val){// 用原生方式实现可响应
            this[name] = val;
            this.render();
            return this[name];
        }
    }
    let cmp3 = new Cmp3('oy3');






    
    </script>
</body>
</html>